/*
 $License:
    Copyright (C) 2011-2012 InvenSense Corporation, All Rights Reserved.
    See included License.txt for License information.
 $
 */
/**
 *  @addtogroup  DRIVERS Sensor Driver Layer
 *  @brief       Hardware drivers to communicate with sensors via I2C.
 *
 *  @{
 *      @file       inv_mpu.h
 *      @brief      An I2C-based driver for Invensense gyroscopes.
 *      @details    This driver currently works for the following devices:
 *                  MPU6050
 *                  MPU6500
 *                  MPU9150 (or MPU6050 w/ AK8975 on the auxiliary bus)
 *                  MPU9250 (or MPU6500 w/ AK8963 on the auxiliary bus)
 */

#ifndef _INV_MPU_H_
#define _INV_MPU_H_
#include "main.h"

// ����˵stm32Ӳ��i2c�ӿ��ļ�
#include "i2c.h"

/*******************************�Զ��庯��************************************/

/*mpu6050���ݶ�ȡ����
 *
 * 1���������ļ�������ͷ�ļ���inv_mpu.h"
 * 2������һЩ�����洢�����ȡ�����ݣ���float pitch
 * 3�����ó�ʼ����������ʹ��dmp��MPU_Init(I2C_HandleTypeDef *hi2c_),
 *                   ʹ��dmp�Ļ�����MPU_Dmp_Init(I2C_HandleTypeDef *hi2c_)
 *                   ������Ĳ���Ϊ���õ�iic�ӿھ������&hi2c1��
 * 4����ȡ�¶�ֵ��float�ͣ�������MPU_Get_Temperature(float *temperature)
 * 5����ȡ����������ԭʼ���ݣ�short\i16���ͣ�����MPU_Get_Gyroscope(short *gx,short *gy,short *gz)
 * 6����ȡ���ٶȼ�����ԭʼ���ݣ�short\i16���ͣ�����MPU_Get_Accelerometer(short *ax,short *ay,short *az)
 * 7����ȡ��dmp��õ�ŷ���ǣ�float�ͣ�������MPU_DMP_Get_Data(float *pitch,float *roll,float *yaw)
 */

int MPU_Init(I2C_HandleTypeDef *hi2c_);     // mpu6050��ʼ��
int MPU_Dmp_Init(I2C_HandleTypeDef *hi2c_); // mpu6050+dmp��ʼ��

int MPU_Write_Len(uint8_t addr, uint8_t reg, uint8_t len, uint8_t *buf); // IIC����д
int MPU_Read_Len(uint8_t addr, uint8_t reg, uint8_t len, uint8_t *buf);  // IIC������
int MPU_Write_Byte(uint8_t reg, uint8_t data);                           // IICдһ���ֽ�
uint8_t MPU_Read_Byte(uint8_t reg);                                      // IIC��һ���ֽ�

int MPU_Set_Gyro_Fsr(uint8_t fsr);  // ���������������̷�Χ
int MPU_Set_Accel_Fsr(uint8_t fsr); // ���ü��ټ������̷�Χ
int MPU_Set_LPF(uint16_t lpf);      // �������ֵ�ͨ�˲�Ƶ��
int MPU_Set_Rate(uint16_t rate);    // ���ò���Ƶ��
int MPU_Set_Fifo(uint8_t sens);     // �����Ƚ��ȳ������У��Ĵ���

int MPU_Get_Temperature(float *temperature);                     // ��ȡ�¶ȼ�ֵ
int MPU_Get_Gyroscope(short *gx, short *gy, short *gz);          // ��ȡ����������ԭʼ����
int MPU_Get_Accelerometer(short *ax, short *ay, short *az);      // ��ȡ���ٶȼ�����ԭʼ����
uint8_t MPU_DMP_Get_Data(float *pitch, float *roll, float *yaw); // ��ȡdmp���ݣ�����Ԫ��תΪŷ���ǣ�

int run_self_test(void);                                                 // mpu6050�Բ���
unsigned short inv_row_2_scale(const signed char *row);                  // ����ת��
unsigned short inv_orientation_matrix_to_scalar(const signed char *mtx); // �����Ƿ�����ƣ���������ת������
void mget_ms(unsigned long *timestamp);                                  // �պ���

/***********************�Լ����ӵ�������ַ�궨��*****************************/

#define MPU_SELF_TESTX_REG 0X0D   // �Լ�Ĵ���X
#define MPU_SELF_TESTY_REG 0X0E   // �Լ�Ĵ���Y
#define MPU_SELF_TESTZ_REG 0X0F   // �Լ�Ĵ���Z
#define MPU_SELF_TESTA_REG 0X10   // �Լ�Ĵ���A
#define MPU_SAMPLE_RATE_REG 0X19  // ����Ƶ�ʷ�Ƶ��
#define MPU_CFG_REG 0X1A          // ���üĴ���
#define MPU_GYRO_CFG_REG 0X1B     // ���������üĴ���
#define MPU_ACCEL_CFG_REG 0X1C    // ���ٶȼ����üĴ���
#define MPU_MOTION_DET_REG 0X1F   // �˶���ֵⷧ���üĴ���
#define MPU_FIFO_EN_REG 0X23      // FIFOʹ�ܼĴ���
#define MPU_I2CMST_CTRL_REG 0X24  // IIC�������ƼĴ���
#define MPU_I2CSLV0_ADDR_REG 0X25 // IIC�ӻ�0������ַ�Ĵ���
#define MPU_I2CSLV0_REG 0X26      // IIC�ӻ�0���ݵ�ַ�Ĵ���
#define MPU_I2CSLV0_CTRL_REG 0X27 // IIC�ӻ�0���ƼĴ���
#define MPU_I2CSLV1_ADDR_REG 0X28 // IIC�ӻ�1������ַ�Ĵ���
#define MPU_I2CSLV1_REG 0X29      // IIC�ӻ�1���ݵ�ַ�Ĵ���
#define MPU_I2CSLV1_CTRL_REG 0X2A // IIC�ӻ�1���ƼĴ���
#define MPU_I2CSLV2_ADDR_REG 0X2B // IIC�ӻ�2������ַ�Ĵ���
#define MPU_I2CSLV2_REG 0X2C      // IIC�ӻ�2���ݵ�ַ�Ĵ���
#define MPU_I2CSLV2_CTRL_REG 0X2D // IIC�ӻ�2���ƼĴ���
#define MPU_I2CSLV3_ADDR_REG 0X2E // IIC�ӻ�3������ַ�Ĵ���
#define MPU_I2CSLV3_REG 0X2F      // IIC�ӻ�3���ݵ�ַ�Ĵ���
#define MPU_I2CSLV3_CTRL_REG 0X30 // IIC�ӻ�3���ƼĴ���
#define MPU_I2CSLV4_ADDR_REG 0X31 // IIC�ӻ�4������ַ�Ĵ���
#define MPU_I2CSLV4_REG 0X32      // IIC�ӻ�4���ݵ�ַ�Ĵ���
#define MPU_I2CSLV4_DO_REG 0X33   // IIC�ӻ�4д���ݼĴ���
#define MPU_I2CSLV4_CTRL_REG 0X34 // IIC�ӻ�4���ƼĴ���
#define MPU_I2CSLV4_DI_REG 0X35   // IIC�ӻ�4�����ݼĴ���

#define MPU_I2CMST_STA_REG 0X36 // IIC����״̬�Ĵ���
#define MPU_INTBP_CFG_REG 0X37  // �ж�/��·���üĴ���
#define MPU_INT_EN_REG 0X38     // �ж�ʹ�ܼĴ���
#define MPU_INT_STA_REG 0X3A    // �ж�״̬�Ĵ���

#define MPU_ACCEL_XOUTH_REG 0X3B // ���ٶ�ֵ,X���8λ�Ĵ���
#define MPU_ACCEL_XOUTL_REG 0X3C // ���ٶ�ֵ,X���8λ�Ĵ���
#define MPU_ACCEL_YOUTH_REG 0X3D // ���ٶ�ֵ,Y���8λ�Ĵ���
#define MPU_ACCEL_YOUTL_REG 0X3E // ���ٶ�ֵ,Y���8λ�Ĵ���
#define MPU_ACCEL_ZOUTH_REG 0X3F // ���ٶ�ֵ,Z���8λ�Ĵ���
#define MPU_ACCEL_ZOUTL_REG 0X40 // ���ٶ�ֵ,Z���8λ�Ĵ���

#define MPU_TEMP_OUTH_REG 0X41 // �¶�ֵ�߰�λ�Ĵ���
#define MPU_TEMP_OUTL_REG 0X42 // �¶�ֵ��8λ�Ĵ���

#define MPU_GYRO_XOUTH_REG 0X43 // ������ֵ,X���8λ�Ĵ���
#define MPU_GYRO_XOUTL_REG 0X44 // ������ֵ,X���8λ�Ĵ���
#define MPU_GYRO_YOUTH_REG 0X45 // ������ֵ,Y���8λ�Ĵ���
#define MPU_GYRO_YOUTL_REG 0X46 // ������ֵ,Y���8λ�Ĵ���
#define MPU_GYRO_ZOUTH_REG 0X47 // ������ֵ,Z���8λ�Ĵ���
#define MPU_GYRO_ZOUTL_REG 0X48 // ������ֵ,Z���8λ�Ĵ���

#define MPU_I2CSLV0_DO_REG 0X63 // IIC�ӻ�0���ݼĴ���
#define MPU_I2CSLV1_DO_REG 0X64 // IIC�ӻ�1���ݼĴ���
#define MPU_I2CSLV2_DO_REG 0X65 // IIC�ӻ�2���ݼĴ���
#define MPU_I2CSLV3_DO_REG 0X66 // IIC�ӻ�3���ݼĴ���

#define MPU_I2CMST_DELAY_REG 0X67 // IIC������ʱ�����Ĵ���
#define MPU_SIGPATH_RST_REG 0X68  // �ź�ͨ����λ�Ĵ���
#define MPU_MDETECT_CTRL_REG 0X69 // �˶������ƼĴ���
#define MPU_USER_CTRL_REG 0X6A    // �û����ƼĴ���
#define MPU_PWR_MGMT1_REG 0X6B    // ��Դ�����Ĵ���1
#define MPU_PWR_MGMT2_REG 0X6C    // ��Դ�����Ĵ���2
#define MPU_FIFO_CNTH_REG 0X72    // FIFO�����Ĵ����߰�λ
#define MPU_FIFO_CNTL_REG 0X73    // FIFO�����Ĵ����Ͱ�λ
#define MPU_FIFO_RW_REG 0X74      // FIFO��д�Ĵ���
#define MPU_DEVICE_ID_REG 0X75    // ����ID�Ĵ���

// AD0��(9��)�ӵ�,IIC��ַΪ0X68(���������λ).
// AD0��V3.3,��IIC��ַΪ0X69(���������λ).
#define MPU_ADDR 0X68
// #define MPU_ADDR                0x69

/*****************************һ���ǹٷ���װ��***********************************/

#define INV_X_GYRO (0x40)
#define INV_Y_GYRO (0x20)
#define INV_Z_GYRO (0x10)
#define INV_XYZ_GYRO (INV_X_GYRO | INV_Y_GYRO | INV_Z_GYRO)
#define INV_XYZ_ACCEL (0x08)
#define INV_XYZ_COMPASS (0x01)

// ��ֲ�ٷ�MSP430 DMP��������
struct int_param_s
{
    // #if defined EMPL_TARGET_MSP430 || defined MOTION_DRIVER_TARGET_MSP430
    void (*cb)(void);
    unsigned short pin;
    unsigned char lp_exit;
    unsigned char active_low;
    // #elif defined EMPL_TARGET_UC3L0
    //     unsigned long pin;
    //     void (*cb)(volatile void*);
    //     void *arg;
    // #endif
};

#define MPU_INT_STATUS_DATA_READY (0x0001)
#define MPU_INT_STATUS_DMP (0x0002)
#define MPU_INT_STATUS_PLL_READY (0x0004)
#define MPU_INT_STATUS_I2C_MST (0x0008)
#define MPU_INT_STATUS_FIFO_OVERFLOW (0x0010)
#define MPU_INT_STATUS_ZMOT (0x0020)
#define MPU_INT_STATUS_MOT (0x0040)
#define MPU_INT_STATUS_FREE_FALL (0x0080)
#define MPU_INT_STATUS_DMP_0 (0x0100)
#define MPU_INT_STATUS_DMP_1 (0x0200)
#define MPU_INT_STATUS_DMP_2 (0x0400)
#define MPU_INT_STATUS_DMP_3 (0x0800)
#define MPU_INT_STATUS_DMP_4 (0x1000)
#define MPU_INT_STATUS_DMP_5 (0x2000)

/* Set up APIs */
int mpu_init(void);
int mpu_init_slave(void);
int mpu_set_bypass(unsigned char bypass_on);

/* Configuration APIs */
int mpu_lp_accel_mode(unsigned char rate);
int mpu_lp_motion_interrupt(unsigned short thresh, unsigned char time,
                            unsigned char lpa_freq);
int mpu_set_int_level(unsigned char active_low);
int mpu_set_int_latched(unsigned char enable);

int mpu_set_dmp_state(unsigned char enable);
int mpu_get_dmp_state(unsigned char *enabled);

int mpu_get_lpf(unsigned short *lpf);
int mpu_set_lpf(unsigned short lpf);

int mpu_get_gyro_fsr(unsigned short *fsr);
int mpu_set_gyro_fsr(unsigned short fsr);

int mpu_get_accel_fsr(unsigned char *fsr);
int mpu_set_accel_fsr(unsigned char fsr);

int mpu_get_compass_fsr(unsigned short *fsr);

int mpu_get_gyro_sens(float *sens);
int mpu_get_accel_sens(unsigned short *sens);

int mpu_get_sample_rate(unsigned short *rate);
int mpu_set_sample_rate(unsigned short rate);
int mpu_get_compass_sample_rate(unsigned short *rate);
int mpu_set_compass_sample_rate(unsigned short rate);

int mpu_get_fifo_config(unsigned char *sensors);
int mpu_configure_fifo(unsigned char sensors);

int mpu_get_power_state(unsigned char *power_on);
int mpu_set_sensors(unsigned char sensors);

int mpu_set_accel_bias(const long *accel_bias);

/* Data getter/setter APIs */
int mpu_get_gyro_reg(short *data, unsigned long *timestamp);
int mpu_get_accel_reg(short *data, unsigned long *timestamp);
int mpu_get_compass_reg(short *data, unsigned long *timestamp);
int mpu_get_temperature(long *data, unsigned long *timestamp);

int mpu_get_int_status(short *status);
int mpu_read_fifo(short *gyro, short *accel, unsigned long *timestamp,
                  unsigned char *sensors, unsigned char *more);
int mpu_read_fifo_stream(unsigned short length, unsigned char *data,
                         unsigned char *more);
int mpu_reset_fifo(void);

int mpu_write_mem(unsigned short mem_addr, unsigned short length,
                  unsigned char *data);
int mpu_read_mem(unsigned short mem_addr, unsigned short length,
                 unsigned char *data);
int mpu_load_firmware(unsigned short length, const unsigned char *firmware,
                      unsigned short start_addr, unsigned short sample_rate);

int mpu_reg_dump(void);
int mpu_read_reg(unsigned char reg, unsigned char *data);
int mpu_run_self_test(long *gyro, long *accel);
int mpu_register_tap_cb(void (*func)(unsigned char, unsigned char));

#endif /* #ifndef _INV_MPU_H_ */
